from rest_framework import serializers
from .models import User
from django.db.models import Q


class LoginSerializer(serializers.Serializer):
    """登录序列化器"""
    username = serializers.CharField(
        max_length=50,
        required=True,
        error_messages={
            'required': '用户名不能为空',
            'max_length': '用户名长度不能超过50个字符'
        }
    )
    password = serializers.CharField(
        max_length=255,
        required=True,
        style={'input_type': 'password'},
        error_messages={
            'required': '密码不能为空',
            'max_length': '密码长度不能超过255个字符'
        }
    )

    def validate(self, attrs):
        """验证登录信息"""
        username = attrs.get('username')
        password = attrs.get('password')

        if not username:
            raise serializers.ValidationError('用户名不能为空')

        if not password:
            raise serializers.ValidationError('密码不能为空')

        return attrs


class UserInfoSerializer(serializers.ModelSerializer):
    """用户信息序列化器"""
    role_display = serializers.CharField(source='get_role_display', read_only=True)
    status_display = serializers.CharField(source='get_status_display', read_only=True)
    gender_display = serializers.CharField(source='get_gender_display', read_only=True)

    class Meta:
        model = User
        fields = [
            'id', 'username', 'email', 'real_name', 'phone', 'gender', 'gender_display',
            'birth_date', 'role', 'role_display', 'status', 'status_display',
            'avatar', 'department', 'student_id', 'teacher_id', 'created_at', 'last_login'
        ]


class UserCreateSerializer(serializers.ModelSerializer):
    """用户创建序列化器"""
    password = serializers.CharField(
        write_only=True,
        min_length=6,
        max_length=255,
        error_messages={
            'required': '密码不能为空',
            'min_length': '密码长度至少6个字符',
            'max_length': '密码长度不能超过255个字符'
        }
    )
    confirm_password = serializers.CharField(
        write_only=True,
        error_messages={
            'required': '确认密码不能为空'
        }
    )

    class Meta:
        model = User
        fields = [
            'username', 'password', 'confirm_password', 'email', 'real_name',
            'phone', 'gender', 'birth_date', 'role', 'status', 'department',
            'student_id', 'teacher_id'
        ]

    def validate_username(self, value):
        """验证用户名唯一性"""
        if User.objects.filter(username=value).exists():
            raise serializers.ValidationError('用户名已存在')
        return value

    def validate_email(self, value):
        """验证邮箱唯一性"""
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError('邮箱已存在')
        return value

    def validate_student_id(self, value):
        """验证学号唯一性"""
        if value and User.objects.filter(student_id=value).exists():
            raise serializers.ValidationError('学号已存在')
        return value

    def validate_teacher_id(self, value):
        """验证工号唯一性"""
        if value and User.objects.filter(teacher_id=value).exists():
            raise serializers.ValidationError('工号已存在')
        return value

    def validate(self, attrs):
        """验证密码一致性和角色相关字段"""
        password = attrs.get('password')
        confirm_password = attrs.get('confirm_password')
        role = attrs.get('role')
        student_id = attrs.get('student_id')
        teacher_id = attrs.get('teacher_id')

        # 验证密码一致性
        if password != confirm_password:
            raise serializers.ValidationError('两次输入的密码不一致')

        # 验证角色相关字段
        if role == 'student':
            if not student_id:
                raise serializers.ValidationError('学生角色必须填写学号')
            if teacher_id:
                attrs['teacher_id'] = None  # 清空工号
        elif role == 'teacher':
            if not teacher_id:
                raise serializers.ValidationError('教师角色必须填写工号')
            if student_id:
                attrs['student_id'] = None  # 清空学号
        else:  # admin
            if student_id:
                attrs['student_id'] = None
            if teacher_id:
                attrs['teacher_id'] = None

        # 移除确认密码字段
        attrs.pop('confirm_password', None)

        return attrs

    def create(self, validated_data):
        """创建用户"""
        password = validated_data.pop('password')
        user = User.objects.create(**validated_data)
        user.set_password(password)
        user.save()
        return user


class UserUpdateSerializer(serializers.ModelSerializer):
    """用户更新序列化器"""
    password = serializers.CharField(
        write_only=True,
        required=False,
        allow_blank=True,
        min_length=6,
        max_length=255,
        error_messages={
            'min_length': '密码长度至少6个字符',
            'max_length': '密码长度不能超过255个字符'
        }
    )
    confirm_password = serializers.CharField(
        write_only=True,
        required=False,
        allow_blank=True
    )

    class Meta:
        model = User
        fields = [
            'username', 'password', 'confirm_password', 'email', 'real_name',
            'phone', 'gender', 'birth_date', 'role', 'status', 'department',
            'student_id', 'teacher_id'
        ]

    def validate_username(self, value):
        """验证用户名唯一性（排除当前用户）"""
        if User.objects.filter(username=value).exclude(id=self.instance.id).exists():
            raise serializers.ValidationError('用户名已存在')
        return value

    def validate_email(self, value):
        """验证邮箱唯一性（排除当前用户）"""
        if User.objects.filter(email=value).exclude(id=self.instance.id).exists():
            raise serializers.ValidationError('邮箱已存在')
        return value

    def validate_student_id(self, value):
        """验证学号唯一性（排除当前用户）"""
        if value and User.objects.filter(student_id=value).exclude(id=self.instance.id).exists():
            raise serializers.ValidationError('学号已存在')
        return value

    def validate_teacher_id(self, value):
        """验证工号唯一性（排除当前用户）"""
        if value and User.objects.filter(teacher_id=value).exclude(id=self.instance.id).exists():
            raise serializers.ValidationError('工号已存在')
        return value

    def validate(self, attrs):
        """验证密码一致性和角色相关字段"""
        password = attrs.get('password')
        confirm_password = attrs.get('confirm_password')
        role = attrs.get('role', self.instance.role)
        student_id = attrs.get('student_id')
        teacher_id = attrs.get('teacher_id')

        # 验证密码一致性（如果提供了密码）
        if password or confirm_password:
            if password != confirm_password:
                raise serializers.ValidationError('两次输入的密码不一致')

        # 验证角色相关字段
        if role == 'student':
            # 如果角色是学生，确保有学号
            if student_id is None and not self.instance.student_id:
                raise serializers.ValidationError('学生角色必须填写学号')
            if teacher_id == '':  # 如果传入空字符串，清空工号
                attrs['teacher_id'] = None
        elif role == 'teacher':
            # 如果角色是教师，确保有工号
            if teacher_id is None and not self.instance.teacher_id:
                raise serializers.ValidationError('教师角色必须填写工号')
            if student_id == '':  # 如果传入空字符串，清空学号
                attrs['student_id'] = None
        else:  # admin
            if student_id == '':
                attrs['student_id'] = None
            if teacher_id == '':
                attrs['teacher_id'] = None

        # 移除确认密码字段
        attrs.pop('confirm_password', None)

        return attrs

    def update(self, instance, validated_data):
        """更新用户"""
        password = validated_data.pop('password', None)

        # 更新其他字段
        for attr, value in validated_data.items():
            setattr(instance, attr, value)

        # 如果提供了新密码，则更新密码
        if password:
            instance.set_password(password)

        instance.save()
        return instance